package com.itrip.controller;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.itrip.dto.ResponseDTO;
import com.itrip.mail.RegisterMail;
import com.itrip.pojo.ItripUser;
import com.itrip.service.UserService;
import com.itrip.utils.MD5;
import com.itrip.utils.RegisterMsg;
import com.itrip.vo.user.LoginVO;
import com.itrip.vo.user.RegisterVO;
import io.swagger.annotations.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;



/**
 * 登录，注销，注册
 *  控制器
 */
@Api(tags = "登录，注销，注册相关接口")
@ApiResponses({
        @ApiResponse(code = 200, message = "请求正常", response = ResponseDTO.class)
})
@RestController
public class LoginController {

    @Resource
    private UserService userService;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * 获取账号出现次数，判断是否注册
     */
    @ApiOperation("获取短信激活码接口")
    @ApiImplicitParam(name = "phone", value = "注册用户的手机号", required = true)
    @GetMapping("/getCodeForPhone")
    public ResponseDTO getCodeForPhone(@RequestParam String phone) throws Exception {
        //生成6位随机数
        int code = (int)((Math.random()*9+1)*100000);
        //发送短信验证码
        String send = RegisterMsg.send(phone, code);
        String resultCode = JSONObject.parseObject(send).getString("Code");
        if(!StringUtils.isEmpty(resultCode) && resultCode.equals("OK")){
            //短信发送成功
            //将激活码存到Redis,有效期5分钟
            redisTemplate.opsForValue().set(phone,code,5,TimeUnit.MINUTES);
            return new ResponseDTO(100,"短信验证码发送成功",null);
        }
        return new ResponseDTO(101,"短信验证码发送失败",null);
    }


    /**
     * 获取账号出现次数，判断是否注册
     */
    @ApiOperation("获取账号是否已注册")
    @ApiImplicitParam(name = "userCode", value = "注册账号", required = true)
    @GetMapping("/getUserCodeCount")
    public ResponseDTO getUserCodeCount(@RequestParam String userCode) throws Exception {
        //查询邮箱出现次数
        int count = userService.getUserCodeCount(userCode);

        String mgs = count>0?"账号已存在":"账号不存在";
        return new ResponseDTO(100,mgs,count);
    }

    /**
     * 获取邮件激活码接口
     */
    @ApiOperation("获取邮件激活码接口")
    @ApiImplicitParam(name = "email", value = "注册用户的邮箱地址", required = true)
    @GetMapping("/getCodeForMail")
    public ResponseDTO getCodeForMail(@RequestParam String email) throws Exception {
        //生成6位随机数
        int code = (int)((Math.random()*9+1)*100000);
        //发送邮件
        RegisterMail.sendMail(code,email);

        //将激活码存到Redis,有效期5分钟
        redisTemplate.opsForValue().set(email,code,5,TimeUnit.MINUTES);
        return new ResponseDTO(100,"邮件发送成功",null);
    }

    /**
     * 用户邮件注册接口
     * @param registerVO 请求参数
     */
    @ApiOperation("用户邮件注册接口")
    @PostMapping(value = "/register",params = {"userCode","userPassword","code"})
    public ResponseDTO register(RegisterVO registerVO){

        //1.根据邮件获取相应的激活码
        Object code = redisTemplate.opsForValue().get(registerVO.getUserCode());
        //2.判断邮箱对应的激活码是否输入正确
        if(code != null && code.toString().equals(registerVO.getCode())){
            //激活码正确，删除激活码
            redisTemplate.delete(registerVO.getUserCode());

            //将VO转为POJO
            ItripUser user = new ItripUser();
            user.setUserCode(registerVO.getUserCode());
            user.setUserPassword(MD5.md5(registerVO.getUserPassword()));
            //填充其它用户信息
            user.setUserType(0);//自注册用户
            user.setUserName(registerVO.getUserCode());//用户默认昵称
            user.setCreationDate(new Date());//创建时间
            user.setActivated(1);//已激活

            //将POJO存储到数据库
            int count = userService.addUser(user);
            if(count == 1){//注册成功
                //生成token令牌
                String token = UUID.randomUUID().toString();
                //存储token令牌到Redis,30分钟有效期
                redisTemplate.opsForValue().set(token,user,30, TimeUnit.MINUTES);

                return new ResponseDTO(100,"注册成功",token);
            }
            return new ResponseDTO(101,"注册失败",null);
        }

        //激活码错误
        return new ResponseDTO(101,"激活码无效",null);
    }

    @ApiOperation("获取邮件快速登录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userCode",value = "手机/邮箱",required = true),
            @ApiImplicitParam(name = "code",value = "验证码", required = true)
    })
    @GetMapping("/getQuickLoginUser")
    public ResponseDTO getQuickLoginUser(@RequestParam String userCode,@RequestParam String Code){
                //1.根据邮件获取相应的激活码
        Object code = redisTemplate.opsForValue().get(userCode);
        //2.判断邮箱对应的激活码是否输入正确
        if(code != null && code.toString().equals(Code)){
            //激活码正确，删除激活码
            redisTemplate.delete(userCode);

            int count =userService.getUserCodeCount(userCode);
            if (count > 0){
                //生成token令牌
                String token = UUID.randomUUID().toString();
                //存储token令牌到Redis,30分钟有效期
                redisTemplate.opsForValue().set(token,userCode,30, TimeUnit.MINUTES);
                return new ResponseDTO(100,"登录成功",token);
            }

            ItripUser user = new ItripUser();
            user.setUserCode(userCode);
            //将POJO存储到数据库
            int count1 = userService.addUser(user);
            if (count1 == 1){
                //生成token令牌
                String token = UUID.randomUUID().toString();
                //存储token令牌到Redis,30分钟有效期
                redisTemplate.opsForValue().set(token,user,30, TimeUnit.MINUTES);

                return new ResponseDTO(100,"注册成功并登录成功",token);
            }
            return new ResponseDTO(102,"注册失败并登录失败",null);
        }
        return new ResponseDTO(101,"激活码无效",null);


    }

    /**
     * 获取登录用户接口
     */
    @ApiOperation("获取登录用户接口")
    @ApiImplicitParam(name = "token", value = "token令牌", dataType = "string", paramType = "header", required = true)
    @GetMapping("/view/getLoginUser")
    public ResponseDTO getLoginUser(HttpServletRequest request){
        //从请求头中，获取token令牌
        String token = request.getHeader("token");

        //根据token从Redis中获取相应的用户
        Object user = redisTemplate.opsForValue().get(token);

        return new ResponseDTO(100,"获取登录用户成功",user);
    }



    /**
     * 注销
     * @param request
     * @return
     */
    @ApiOperation("用户注销接口")
    @ApiImplicitParam(name = "token", value = "token令牌", dataType = "string", paramType = "header", required = true)
    @GetMapping("/view/logout")
    public ResponseDTO logout(HttpServletRequest request){
        //从请求头中，获取token令牌
        String token = request.getHeader("token");
        //从Redis中删除token
        redisTemplate.delete(token);
        return new ResponseDTO(100,"注销成功",null);
    }
    /**
     * 用户登录
     * @param loginVO 用户登录
     * @return 响应结果
     */
    @ApiOperation("用户登录接口")
    @PostMapping (value = "/login", params = {"userCode","userPassword"})
    public ResponseDTO login(LoginVO loginVO){

        //MD5加密后匹配密文
        loginVO.setUserPassword(MD5.md5(loginVO.getUserPassword()));

        //根据登录查询用户信息
       ItripUser user = userService.getUserByLogin(loginVO);
       if (user != null){
           //登录成功，生成token令牌
           String token = UUID.randomUUID().toString();
           //存储token令牌到redis数据库，30分钟有效期
           redisTemplate.opsForValue().set(token,user,30, TimeUnit.MINUTES);
           return new ResponseDTO(100,"登录成功",token);
       }
       return new ResponseDTO(101,"登录失败",null);
    }
}
